Aus Oxoscript wird NanoPy - mehr Infos

Netzwerk-Funktionen

clearRequestHeaders

  clearRequestHeaders()

Löscht alle vorhin hinzugefügten HTTP Header.

addRequestHeader

  addRequestHeader(key:byte[], value:byte[])

Fügt nachfolgenden Requests einen HTTP Header hinzu.

Beispiel:

addRequestHeader("Content-Type", "application/json")
addRequestHeader("Content-Length", strLen(body))
addRequestHeader("Authorization", "Bearer " + apiKey)

getMQTTData

  getMQTTData()->byte[1024]

Sobald mit der hasMQTTMessage() -Funktion festgestellt wurde, dass eine MQTT Nachricht empfangen wurde, kann mit dieser Funktion die empfangenen Daten ausgelesen werden.

if hasMQTTMessage():
    data = getMQTTData()

Limitierungen:
- Es können maximal 1024 Bytes ausgelesen werden. Längere Daten werden einer neuen Nachricht ohne Topic angehängt.

getMQTTTopic

  getMQTTTopic()->byte[48]

Sobald mit der hasMQTTMessage() -Funktion festgestellt wurde, dass eine MQTT Nachricht empfangen wurde, kann mit dieser Funktion den empfangenen Topic ausgelesen werden.

if hasMQTTMessage():
    topic = getMQTTTopic()

hasMQTTMessage

  hasMQTTMessage()->bool

Gibt true zurück, wenn eine MQTT Nachricht empfangen wurde.

Empfangene Daten können anschliessend mit den folgenden Funktionen gelsen werden:

getMQTTTopic()
getMQTTData()

unsubscribeMQTT

  unsubscribeMQTT(topic:byte[])->int

Für diese Funktion muss die Karte mit dem Internet und einem MQTT broker verbunden sein.

Meldet das zuvor abonnierte Topic ab.
Die Funktion gibt im Erfolgsfall eine msgId zurück oder -1 im Fehlerfall.

subscribeMQTT

  subscribeMQTT(topic:byte[])->int

Für diese Funktion muss die Karte mit dem Internet und einem MQTT broker verbunden sein.

Abonniert das definierte Topic, um publizierte Nachrichten empfangen zu können.
Die Funktion gibt im Erfolgsfall eine msgId zurück oder -1 im Fehlerfall.

Empfangene Nachrichten können anschliessend mit den folgenden Funktionen gelsen werden:

hasMQTTMessage()
getMQTTTopic()
getMQTTData()

Beispiel:

uri = "mqtt://broker.hivemq.com"
username = ""
password = ""

if connectMQTT(uri, username, password):
    subscribeMQTT("myTopic")

def onDraw():
    if hasMQTTMessage():
        print(getMQTTTopic())
        print(getMQTTData())
    delay(100)

publishMQTT

  publishMQTT(topic:byte[], data:byte[])->int

Für diese Funktion muss die Karte mit dem Internet und einem MQTT broker verbunden sein.

Publiziert eine Nachricht (data) unter dem definierte Topic.
Die Funktion gibt im Erfolgsfall eine msgId zurück, 0 wenn QoS = 0 oder -1 im Fehlerfall.

Beispiel:

uri = "mqtt://broker.hivemq.com"
username = ""
password = ""

if connectMQTT(uri, username, password):
    publishMQTT("myTopic", "myData")

disconnectMQTT

  disconnectMQTT()

Für diese Funktion muss die Karte mit dem Internet und einem MQTT broker verbunden sein.

Trennt die Verbindung zu einem MQTT broker.

connectMQTT

  connectMQTT(uri:byte[], username:byte[], password:byte[])->bool

Für diese Funktion muss die Karte mit dem Internet verbunden sein.

Verbindet die Oxocard mit einem MQTT broker. Die Funktion gibt true zurück, falls das Verbinden erfolgreich war.

Username und Password können leer sein, wenn keine Authentifizierung benötigt wird.

Beispiel:

# Public MQTT broker (unsecure): https://www.mqtt-dashboard.com/
uri = "mqtt://broker.hivemq.com"
username = ""
password = ""

# # Personal MQTT broker (secure): https://console.hivemq.cloud
# uri = "mqtts://abc.s2.eu.hivemq.cloud:8883"
# username = "myUsername"
# password = "myPassword123"

subscribeTopic = "myTopic"
publishTopic = "myTopic"
publishData = "myData string"

title = "MQTT MSG"
drawText(120-textWidth(title)/2, 5, title)
update()

if connectMQTT(uri, username, password):
    subscribeMQTT(subscribeTopic)
else:
    drawText(10, 55, "connect failed!")
    update()

def onDraw():
    if hasMQTTMessage():
        clear()
        textFont(FONT_ROBOTO_32)
        drawText(120-textWidth(title)/2, 5, title)
        topic = getMQTTTopic()
        textFont(FONT_ROBOTO_32)
        drawText(10, 55, "topic:")
        textFont(FONT_ROBOTO_24)
        drawText(20, 95, topic)
        data = getMQTTData()
        textFont(FONT_ROBOTO_32)
        drawText(10, 150, "data:")
        textFont(FONT_ROBOTO_24)
        drawText(20, 190, data)
        update()
    buttonByte = getButton()
    if buttonByte > 0:
        publishMQTT(publishTopic, publishData)
        if buttonByte == 4:
            if returnToMenu():
                return
        while getButton(): delay(10)
    delay(100)

Beachte:
Am Anfang der URI muss das Protokoll definiert werden: “mqtt://…” oder “mqtts://…”.
Bei Bedarf kann dem host auch einen Port angehängt werden (“…:8883”).

selectCertificate

  selectCertificate(path:byte[])

Mit dieser Funktion kann ein eigenes Zertifikat (.pem) im Dateisystem der Oxocard ausgewählt werden.

Dies ist nur nötig, wenn das Zertifikat nicht automatisch angefragt und im “certs”-Ordner der Oxocard abgelegt werden konnte.

Beispiel:

selectCertificate("certs/nanopy-io.pem")

Beachte:
Das eigene Zertifikat (.pem) muss vorgängig z.B. via File Browser im Dateisystem der Oxocard abgelegt werden.

Einleitung MQTT

MQTT steht für “Message Queuing Telemetry Transport”. Das Protokoll besteht aus Regeln, die festlegen, wie IoT-Geräte Daten über das Internet veröffentlichen und abonnieren können. Das Protokoll verbindet Geräte mithilfe des (Pub/Sub)-Musters. Der Sender (Publisher) und der Empfänger (Subscriber) kommunizieren über sogenannte Topics und sind voneinander entkoppelt. Die Verbindung zwischen ihnen wird von einem MQTT-Server (“Broker”) verwaltet.

In nachfolgendem Beispiel subscribed und published die Oxocard auf das selbe Topic und kann so (via MQTT-Broker) die eigenen Nachrichten empfangen.
Als Broker wird der öffentliche gratis Server von HiveMQ verwendet.

Beispiel:

# Public MQTT broker (unsecure): https://www.mqtt-dashboard.com/
uri = "mqtt://broker.hivemq.com"
username = ""
password = ""

subscribeTopic = "myTopic"
publishTopic = "myTopic"
publishData = "myData string"

title = "MQTT MSG"
drawText(120-textWidth(title)/2, 5, title)
update()

if connectMQTT(uri, username, password):
    subscribeMQTT(subscribeTopic)
else:
    drawText(10, 55, "connect failed!")
    update()

def onDraw():
    if hasMQTTMessage():
        clear()
        textFont(FONT_ROBOTO_32)
        drawText(120-textWidth(title)/2, 5, title)
        topic = getMQTTTopic()
        textFont(FONT_ROBOTO_32)
        drawText(10, 55, "topic:")
        textFont(FONT_ROBOTO_24)
        drawText(20, 95, topic)
        data = getMQTTData()
        textFont(FONT_ROBOTO_32)
        drawText(10, 150, "data:")
        textFont(FONT_ROBOTO_24)
        drawText(20, 190, data)
        update()
    buttonByte = getButton()
    if buttonByte > 0:
        publishMQTT(publishTopic, publishData)
        if buttonByte == 4:
            if returnToMenu():
                return
        while getButton(): delay(10)
    delay(100)

Einleitung HTTP/HTTPS

Das Hypertext Transfer Protocol (HTTP) ist entwickelt worden, um die Kommunikation zwischen Clients und Servern zu ermöglichen.
HTTP Secure (HTTPS) ist die sichere Version des HTTP-Protokolls.

Die Oxocard unterstützt die beiden am häufigsten verwendeten HTTP-Methoden: GET und POST.

GET Beispiel:

# Request and display IP
url = "http://httpbin.org/ip"
if (getRequest(url)):
    origin = readRequestJSON("origin")
    drawText(10, 10, origin)
else:
    drawText(10, 10, "error")
update()

POST Beispiel:

# Post simple JSON
url = "https://httpbin.org/post"
body = "{\"field1\":\"value1\"}"
print("sending POST request...")
if (postRequest(url, body)):
    print("ok")
else:
    print("error")

Einleitung Netzwerk

Wenn die Oxocard mit dem Internet verbunden ist, kann sie mit der Hilfe der Netzwerk-Funktionen mit der Welt kommunizieren.

Im Moment unterstützt sie einfache HTTP/HTTPS-Requests und MQTT/MQTTS.

Das bei gesicherten Protokollen (https & mqtts) benötigte Serverzertifikat, wird jeweils zuerst im internen CA store geprüft und sonst im Dateisystem der Oxocard im “certs”-Ordner gesucht. Wenn es nicht vorhanden ist, wird es via unserem Server beim Zielserver angefragt (openssl). Alternativ kann auch selbst ein Zertifikat hinzugefügt werden und mit der selectCertificate()-Funktion darauf verwiesen werden.

postRequest

  postRequest(url:byte[], body:byte[])->bool

Für diese Funktion muss die Karte mit dem Internet verbunden sein.

Sendet eine POST-Anfrage an die definierte URL.
Die Funktion gibt true zurück, falls die Anfrage erfolgreich war (200 OK).

Allfällige Serverantworten können anschliessend mit den folgenden Funktionen gelesen werden:

readRequestLength()
readRequest(offset)
readRequestJSON(jsonPath)

Beispiel:

# Toggle Shelly relay
url = "http://192.168.42.146/relay/0"
body = "turn=toggle"
def onDraw():
    if getButton():
        postRequest(url, body)
        while(getButton()): delay(50)
    delay(50)

readRequestJSON

  readRequestJSON(jsonPath:byte[])->byte[128]

Gibt den Inhalt einer JSON-Antwort als Text (max. 128 Bytes) der vorher mit getRequest() angeforderten Anfrage zurück.

Mit jsonPath kann der zu lesende Key definiert werden.
Mit ‘.’ oder ‘/’ können auch verschachtelte JSON Objekte ausgewählt werden.

Beispiel1:

url = "http://api.nanopy.io/v1/utc"
getRequest(url) # {"utc":1667912328}
drawText(10, 10, readRequestJSON("utc"))
update()

Beispiel2:

# {
#   "myObj": {
#     "mySubObj": {
#       "myArray": [
#         {"myKey":111},
#         {"myKey":222},
#         {"myKey":333}
#       ],
#     }
#   }
# }
readRequestJSON("myObj.mySubObj.myArray.0.myKey") # "111"
readRequestJSON("myObj/mySubObj/myArray/2/myKey") # "333"

Beachte:
readRequestJSON() gibt immer einen String (byte[]) zurück. Mit den stringTo…()-Funktionen kann das Resultat dann in den passenden Datentyp umgewandelt werden.

readRequest

  readRequest(offset:int)->byte[128]

Gibt den Text (max. 128 Bytes) der vorher mit getRequest() angeforderten Anfrage zurück.

Mit offset kann die Startposition definiert werden, die bestimmt ab wo die Antwort gelesen werden soll.
Damit lassen ich auch längere Antworten in mehreren Schritten lesen.

Beispiel:

url = "http://api.nanopy.io/v1/hello_world"
getRequest(url)
drawText(10, 10, readRequest(0))
drawText(10, 50, readRequest(6))
update()

Beachte:
Falls ein eigener Server verwendet und plain-Text zurückgeben werden möchte, muss zwingend auch die ‘Content-Length’ im header definiert werden.

readRequestLength

  readRequestLength()->int

Gibt die länge (in Bytes) der vorher mit getRequest() angeforderten Anfrage zurück.

getRequest

  getRequest(url:byte[])->bool

Für diese Funktion muss die Karte mit dem Internet verbunden sein.

Sendet eine GET-Anfrage an die definierte URL.
Die Funktion gibt true zurück, falls die Anfrage erfolgreich war (200 OK).

Die angefragten Daten können anschliessend mit den folgenden Funktionen gelesen werden:

readRequestLength()
readRequest(offset)
readRequestJSON(jsonPath)

Beispiel:

url = "http://api.nanopy.io/v1/utc"
if (getRequest(url)):
    utc = readRequestJSON("utc")
    drawText(10, 10, stringToInt(utc))
else:
    drawText(10, 10, "error")
update()

Limitierungen:
- Es können maximal 32k Bytes angefrag werden. Längere Antworten werden abgeschnitten